﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;

namespace UsageFileWorker
{
    internal class NativeMethods
    {
        // Fields
        internal const int ERROR_INVALID_HANDLE = 6;
        internal const int ERROR_INVALID_PARAMETER = 0x57;
        internal const int ERROR_SUCCESS = 0;
        internal static Guid EventTraceGuid = new Guid("{68fdd900-4a3e-11d1-84f4-0000f80464e3}");
        internal const int TRACE_VERSION_CURRENT = 1;
        internal const int WNODE_FLAG_TRACED_GUID = 0x20000;



        [StructLayout(LayoutKind.Sequential)]
        internal struct EVENT_TRACE
        {
            public EVENT_TRACE_HEADER Header;
            public uint InstanceId;
            public uint ParentInstanceId;
            public Guid ParentGuid;
            public IntPtr MofData;
            public uint MofLength;
            public uint ClientContext;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct EVENT_TRACE_HEADER
        {
            public ushort Size;
            public ushort FieldTypeFlags;
            public EVENT_TRACE_HEADER_CLASS Class;
            public uint ThreadId;
            public uint ProcessId;
            public long TimeStamp;
            public Guid Guid;
            public uint ClientContext;
            public uint Flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct EVENT_TRACE_HEADER_CLASS
        {
            public byte Type;
            public byte Level;
            public ushort Version;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct EVENT_TRACE_LOGFILE
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string LogFileName;
            [MarshalAs(UnmanagedType.LPWStr)]
            private string LoggerName;
            private ulong CurrentTime;
            private uint BuffersRead;
            private uint LogFileMode;
            private EVENT_TRACE CurrentEvent;
            private TRACE_LOGFILE_HEADER LogfileHeader;
            private IntPtr pBufferCallback;
            private uint BufferSize;
            private uint Filled;
            private uint EventsLost;
            public EventCallback pEventCallback;
            private uint IsKernelTrace;
            private IntPtr Context;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct SYSTEMTIME
        {
            private short wYear;
            private short wMonth;
            private short wDayOfWeek;
            private short wDay;
            private short wHour;
            private short wMinute;
            private short wSecond;
            private short wMilliseconds;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct TIME_ZONE_INFORMATION
        {
            private uint Bias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
            private string StandardName;
            private SYSTEMTIME StandardDate;
            private uint StandardBias;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
            private string DaylightName;
            private SYSTEMTIME DaylightDate;
            private uint DaylightBias;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct TRACE_LOGFILE_HEADER
        {
            private uint BufferSize;
            private uint Version;
            private uint ProviderVersion;
            private uint NumberOfProcessors;
            private long EndTime;
            private uint TimerResolution;
            private uint MaximumFileSize;
            private uint LogFileMode;
            private uint BuffersWritten;
            private uint StartBuffers;
            private uint PointerSize;
            private uint EventsLost;
            private uint CpuSpeedInMHz;
            private IntPtr LoggerName;
            private IntPtr LogFileName;
            private TIME_ZONE_INFORMATION TimeZone;
            private long BootTime;
            private long PerfFreq;
            private long StartTime;
            private uint ReservedFlags;
            private uint BuffersLost;
        }






        internal delegate void EventCallback(ref NativeMethods.EVENT_TRACE pEvent);

 
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern int CloseTrace(long TraceHandle);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        //public static extern unsafe uint EventRegister([In] ref Guid providerId, IntPtr enableCallback, [In] void* context, out ulong regHandle);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        //public static extern uint EventUnregister([In] ulong regHandle);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        //public static extern uint EventWrite([In] ulong regHandle, [In] ref EVENT_DESCRIPTOR EventDescriptor, uint UserDataCount, [MarshalAs(UnmanagedType.LPArray)] EVENT_DATA_DESCRIPTOR[] UserData);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        //internal static extern ulong GetTraceLoggerHandle([In] IntPtr Buffer);
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern long OpenTraceW(ref EVENT_TRACE_LOGFILE Logfile);
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern int ProcessTrace(long[] HandleArray, uint HandleCount, IntPtr StartTime, IntPtr EndTime);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        //internal static extern unsafe uint RegisterTraceGuids([In] EtwProc cbFunc, [In] void* context, [In] ref Guid controlGuid, [In] uint guidCount, IntPtr guidReg, [In] string mofImagePath, [In] string mofResourceName, out ulong regHandle);
        //[DllImport("advapi32.dll")]
        //internal static extern unsafe uint TraceEvent([In] ulong traceHandle, [In] byte* buffer);
        //[DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
        //internal static extern uint UnregisterTraceGuids([In] ulong regHandle);
    }
}
